package com.example.yckjbigdataservice.utils;

import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.regionserver.DelimitedKeyPrefixRegionSplitPolicy;
import org.apache.hadoop.conf.Configuration;

public class HBaseDelimitedSplitPolicyExample {

    public static void main(String[] args) throws Exception {
        Configuration config = HBaseConfiguration.create();
        config.set("hbase.zookeeper.quorum", "localhost");
        config.set("hbase.zookeeper.property.clientPort", "2181");

        try (Connection connection = ConnectionFactory.createConnection(config);
             Admin admin = connection.getAdmin()) {

            // 示例1：使用默认分隔符（下划线）
            createTableWithDefaultDelimiter(admin);

            // 示例2：使用自定义分隔符
            createTableWithCustomDelimiter(admin);

            // 示例3：使用多个分隔符
            createTableWithMultipleDelimiters(admin);

            // 示例4：修改现有表的策略
            // modifyExistingTable(admin, "existing_table");
        }
    }

    /**
     * 使用默认分隔符（下划线 _）创建表
     * 适用于rowkey格式：user_20231201_001
     */
    public static void createTableWithDefaultDelimiter(Admin admin) throws Exception {
        TableName tableName = TableName.valueOf("user_data_table");

        if (admin.tableExists(tableName)) {
            admin.disableTable(tableName);
            admin.deleteTable(tableName);
        }

        // 创建表描述符
        TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tableName);

        // 设置DelimitedKeyPrefixRegionSplitPolicy策略
        tableBuilder.setRegionSplitPolicyClassName(
                DelimitedKeyPrefixRegionSplitPolicy.class.getName());

        // 默认情况下，分隔符是下划线 "_"
        // DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY 的默认值就是 "_"

        // 可选：显式设置分隔符（即使是默认值）
        tableBuilder.setValue(DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY, "_");

        // 设置其他表属性
        tableBuilder.setMaxFileSize(5L * 1024 * 1024 * 1024); // 5GB
        tableBuilder.setMemStoreFlushSize(256L * 1024 * 1024); // 256MB

        // 创建列族
        ColumnFamilyDescriptorBuilder cfBuilder = ColumnFamilyDescriptorBuilder
                .newBuilder("info".getBytes());
        cfBuilder.setMaxVersions(1);
        cfBuilder.setTimeToLive(7 * 24 * 3600); // 7天TTL

        tableBuilder.setColumnFamily(cfBuilder.build());

        // 创建表
        admin.createTable(tableBuilder.build());

        System.out.println("表创建成功：" + tableName.getNameAsString());
        System.out.println("分割策略：DelimitedKeyPrefixRegionSplitPolicy");
        System.out.println("分隔符：_ (下划线)");
        System.out.println("适用rowkey格式：user_20231201_001");
    }

    /**
     * 使用自定义分隔符创建表
     * 适用于rowkey格式：user|20231201|001
     */
    public static void createTableWithCustomDelimiter(Admin admin) throws Exception {
        TableName tableName = TableName.valueOf("custom_delimiter_table");

        if (admin.tableExists(tableName)) {
            admin.disableTable(tableName);
            admin.deleteTable(tableName);
        }

        TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tableName);

        // 设置DelimitedKeyPrefixRegionSplitPolicy策略
        tableBuilder.setRegionSplitPolicyClassName(
                DelimitedKeyPrefixRegionSplitPolicy.class.getName());

        // 设置自定义分隔符为管道符 "|"
        tableBuilder.setValue(DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY, "|");

        // 创建列族
        ColumnFamilyDescriptorBuilder cfBuilder = ColumnFamilyDescriptorBuilder
                .newBuilder("data".getBytes());
        tableBuilder.setColumnFamily(cfBuilder.build());

        // 预分割键（基于前缀）
        byte[][] splitKeys = {
                "user001|".getBytes(),
                "user002|".getBytes(),
                "user003|".getBytes(),
                "user004|".getBytes()
        };

        admin.createTable(tableBuilder.build(), splitKeys);

        System.out.println("表创建成功：" + tableName.getNameAsString());
        System.out.println("分割策略：DelimitedKeyPrefixRegionSplitPolicy");
        System.out.println("分隔符：| (管道符)");
        System.out.println("适用rowkey格式：user001|20231201|001");
    }

    /**
     * 使用正则表达式分隔符创建表
     * 适用于更复杂的分隔符模式
     */
    public static void createTableWithMultipleDelimiters(Admin admin) throws Exception {
        TableName tableName = TableName.valueOf("regex_delimiter_table");

        if (admin.tableExists(tableName)) {
            admin.disableTable(tableName);
            admin.deleteTable(tableName);
        }

        TableDescriptorBuilder tableBuilder = TableDescriptorBuilder.newBuilder(tableName);

        // 设置DelimitedKeyPrefixRegionSplitPolicy策略
        tableBuilder.setRegionSplitPolicyClassName(
                DelimitedKeyPrefixRegionSplitPolicy.class.getName());

        // 使用正则表达式，支持多种分隔符：下划线、冒号、点号
        tableBuilder.setValue(DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY, "[_:.]");

        // 创建列族
        ColumnFamilyDescriptorBuilder cfBuilder = ColumnFamilyDescriptorBuilder
                .newBuilder("metrics".getBytes());
        tableBuilder.setColumnFamily(cfBuilder.build());

        admin.createTable(tableBuilder.build());

        System.out.println("表创建成功：" + tableName.getNameAsString());
        System.out.println("分割策略：DelimitedKeyPrefixRegionSplitPolicy");
        System.out.println("分隔符：[_:.] (正则表达式，支持下划线、冒号、点号)");
        System.out.println("适用rowkey格式：server_cpu.usage 或 server:memory:usage");
    }

    /**
     * 修改现有表的分割策略
     */
    public static void modifyExistingTable(Admin admin, String tableName) throws Exception {
        TableName table = TableName.valueOf(tableName);

        if (!admin.tableExists(table)) {
            System.out.println("表不存在：" + tableName);
            return;
        }

        // 获取现有表描述符
        TableDescriptor oldDescriptor = admin.getDescriptor(table);

        // 创建新的表描述符
        TableDescriptorBuilder newBuilder = TableDescriptorBuilder.newBuilder(oldDescriptor);

        // 修改分割策略
        newBuilder.setRegionSplitPolicyClassName(
                DelimitedKeyPrefixRegionSplitPolicy.class.getName());
        newBuilder.setValue(DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY, "-");

        // 禁用表
        admin.disableTable(table);

        // 修改表
        admin.modifyTable(newBuilder.build());

        // 启用表
        admin.enableTable(table);

        System.out.println("表 " + tableName + " 的分割策略已修改为DelimitedKeyPrefixRegionSplitPolicy");
        System.out.println("新分隔符：- (连字符)");
    }

    /**
     * 验证和显示表的配置信息
     */
    public static void displayTableConfiguration(Admin admin, String tableName) throws Exception {
        TableName table = TableName.valueOf(tableName);

        if (!admin.tableExists(table)) {
            System.out.println("表不存在：" + tableName);
            return;
        }

        TableDescriptor descriptor = admin.getDescriptor(table);

        System.out.println("\n=== 表配置信息 ===");
        System.out.println("表名: " + tableName);
        System.out.println("分割策略: " + descriptor.getRegionSplitPolicyClassName());
        System.out.println("分隔符: " +
                descriptor.getValue(DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY));

        System.out.println("\n=== 列族信息 ===");
        for (ColumnFamilyDescriptor cf : descriptor.getColumnFamilies()) {
            System.out.println("列族: " + cf.getNameAsString());
            System.out.println("  最大版本数: " + cf.getMaxVersions());
            System.out.println("  TTL: " + cf.getTimeToLive() + " 秒");
        }

        System.out.println("\n=== Region信息 ===");
        try (RegionLocator locator = admin.getConnection().getRegionLocator(table)) {
            locator.getAllRegionLocations().forEach(location -> {
                System.out.println("Region: " + location.getRegionInfo().getRegionNameAsString());
                System.out.println("  StartKey: " + new String(location.getRegionInfo().getStartKey()));
                System.out.println("  EndKey: " + new String(location.getRegionInfo().getEndKey()));
            });
        }
    }

    /**
     * 测试数据插入，验证分割策略效果
     */
    public static void testDataInsertion(Connection connection, String tableName) throws Exception {
        TableName table = TableName.valueOf(tableName);

        try (Table hTable = connection.getTable(table)) {
            // 插入测试数据
            String[] userIds = {"user001", "user002", "user003", "user004", "user005"};
            String[] dates = {"20231201", "20231202", "20231203"};

            for (String userId : userIds) {
                for (String date : dates) {
                    for (int i = 1; i <= 3; i++) {
                        String rowKey = userId + "_" + date + "_" + String.format("%03d", i);
                        Put put = new Put(rowKey.getBytes());
                        put.addColumn("info".getBytes(), "data".getBytes(),
                                ("value_" + rowKey).getBytes());
                        hTable.put(put);
                    }
                }
            }

            System.out.println("测试数据插入完成");
            System.out.println("插入的rowkey示例：user001_20231201_001");
            System.out.println("分割将基于第一个下划线前的前缀进行：user001, user002, etc.");
        }
    }
}
